<!DOCTYPE html>
<html>

<head>
    <meta charset='utf-8' />
    <title>Animate a point along a route</title>
    <meta name='viewport' content='initial-scale=1,maximum-scale=1,user-scalable=no' />
    <script src="https://cdn.bootcdn.net/ajax/libs/Turf.js/6.4.0/turf.min.js"></script>
    <script src='https://api.tiles.mapbox.com/mapbox-gl-js/v1.0.0/mapbox-gl.js'></script>
    <link href='https://api.tiles.mapbox.com/mapbox-gl-js/v1.0.0/mapbox-gl.css' rel='stylesheet' />
    <style>
        body {
            margin: 0;
            padding: 0;
        }

        #map {
            position: absolute;
            top: 0;
            bottom: 0;
            width: 100%;
        }
    </style>
</head>

<body>

<style>
    .overlay {
        position: absolute;
        top: 10px;
        left: 10px;
    }

    .overlay button {
        font: 600 12px/20px 'Helvetica Neue', Arial, Helvetica, sans-serif;
        background-color: #3386c0;
        color: #fff;
        display: inline-block;
        margin: 0;
        padding: 10px 20px;
        border: none;
        cursor: pointer;
        border-radius: 3px;
    }

    .overlay button:hover {
        background-color: #4ea0da;
    }
</style>

<div id='map'></div>
<div class='overlay'>
    <input type="button" value="开始" onclick="startClick()" />
    <input type="button" value="暂停" onclick="pauseClick()" />
    <input type="button" value="停止" onclick="stopClick()" />
</div>

<script>


    mapboxgl.accessToken =
        "pk.eyJ1IjoiZnV1aG9vIiwiYSI6ImNraThhaHp4YzAzeWMyeWxidTRmbGM1cWYifQ.lqJPXlzfy9frOrpt_JEc9g";

    let map = new mapboxgl.Map({
        container: 'map',
        style: {
            version: 8,
            sources: {
                google: {
                    type: "raster",
                    tiles: ['https://webst04.is.autonavi.com/appmaptile?style=6&x={x}&y={y}&z={z}'],
                    tileSize: 256,
                },
            },
            layers: [
                {
                    id: "google-tiles1",
                    type: "raster",
                    source: "google",
                },
            ],
        },
        minZoom: 5,
        maxZoom:20,
        center: [112.693000, 39.27415452 ],
        zoom: 14,
        // attributionControl: false
    });

    map.on("load",()=>{

          map.addLayer({
            id: "satellite1",
            type: "raster",
            source: {
              type: "raster",
              tiles: ["http://t0.tianditu.gov.cn/img_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=img&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&tk=18663b944d2bb97a534d169c391404d5"],
            },
          })
          map.addLayer({
            id: "air",
            type: "raster",
            source: {
              type: "raster",
              tiles: ["http://58.56.207.43:9130/szLastMap/{z}/{x}/{y}.png"],
            },
          })
          // map.loadImage(require('@/assets/image/Track.png'), function (error, Track) {
          //   if (Track) {
          //    map.addImage('Track', Track);
          //     setRouteData()
          //   }
          // })
          map.addSource("redLineSource",{type:"geojson",data:{
                  "type": "FeatureCollection",
                  "features": [
                      {
                          "type": "Feature",
                          "geometry": {
                              "type": "LineString",
                              "coordinates": [
                                  [
                                      112.68333136,
                                      39.27709882,
                                      0
                                  ],
                                  [
                                      112.6832598,
                                      39.277138937,
                                      0
                                  ],
                                  [
                                      112.68272351,
                                      39.276888488,
                                      0
                                  ],
                                  [
                                      112.68126743,
                                      39.27877185,
                                      0
                                  ],
                                  [
                                      112.68226057,
                                      39.279235657,
                                      0
                                  ],
                                  [
                                      112.68285136,
                                      39.278471503,
                                      0
                                  ],
                                  [
                                      112.68296862,
                                      39.278442218,
                                      0
                                  ],
                                  [
                                      112.68446828,
                                      39.279142541,
                                      0
                                  ],
                                  [
                                      112.68514856,
                                      39.278262593,
                                      0
                                  ],
                                  [
                                      112.68544965,
                                      39.278187836,
                                      0
                                  ],
                                  [
                                      112.68747572,
                                      39.27913392,
                                      0
                                  ],
                                  [
                                      112.687577,
                                      39.279207477,
                                      0
                                  ],
                                  [
                                      112.68785653,
                                      39.280078615,
                                      0
                                  ],
                                  [
                                      112.68852495,
                                      39.28039072,
                                      0
                                  ],
                                  [
                                      112.68852577,
                                      39.280389662,
                                      0
                                  ],
                                  [
                                      112.69073051,
                                      39.277537454,
                                      0
                                  ],
                                  [
                                      112.69073051,
                                      39.277537454,
                                      0
                                  ],
                                  [
                                      112.69208125,
                                      39.27816812,
                                      0
                                  ],
                                  [
                                      112.69208125,
                                      39.27816812,
                                      0
                                  ],
                                  [
                                      112.69208125,
                                      39.27816812,
                                      0
                                  ],
                                  [
                                      112.69373093,
                                      39.276033739,
                                      0
                                  ],
                                  [
                                      112.69388211,
                                      39.276047986,
                                      0
                                  ],
                                  [
                                      112.70583107,
                                      39.281625744,
                                      0
                                  ],
                                  [
                                      112.70612337,
                                      39.281247465,
                                      0
                                  ],
                                  [
                                      112.70648109,
                                      39.281178076,
                                      0
                                  ],
                                  [
                                      112.70669962,
                                      39.281280067,
                                      0
                                  ],
                                  [
                                      112.70703486,
                                      39.280846203,
                                      0
                                  ],
                                  [
                                      112.70737846,
                                      39.280803832,
                                      0
                                  ],
                                  [
                                      112.70906021,
                                      39.281583429,
                                      0
                                  ],
                                  [
                                      112.71276257,
                                      39.283316374,
                                      0
                                  ],
                                  [
                                      112.71294151,
                                      39.283084764,
                                      0
                                  ],
                                  [
                                      112.71294151,
                                      39.283084764,
                                      0
                                  ],
                                  [
                                      112.70754748,
                                      39.280567595,
                                      0
                                  ],
                                  [
                                      112.70744225,
                                      39.280371433,
                                      0
                                  ],
                                  [
                                      112.7085219,
                                      39.278974099,
                                      0
                                  ],
                                  [
                                      112.70101274,
                                      39.275469189,
                                      0
                                  ],
                                  [
                                      112.70020602,
                                      39.275481266,
                                      0
                                  ],
                                  [
                                      112.69999742,
                                      39.275436407,
                                      0
                                  ],
                                  [
                                      112.67592572,
                                      39.264195044,
                                      0
                                  ],
                                  [
                                      112.67563334,
                                      39.264573242,
                                      0
                                  ],
                                  [
                                      112.67529952,
                                      39.264637918,
                                      0
                                  ],
                                  [
                                      112.6750513,
                                      39.264521954,
                                      0
                                  ],
                                  [
                                      112.67468133,
                                      39.265000492,
                                      0
                                  ],
                                  [
                                      112.67436737,
                                      39.265074442,
                                      0
                                  ],
                                  [
                                      112.67373192,
                                      39.264777566,
                                      0
                                  ],
                                  [
                                      112.67356483,
                                      39.264993678,
                                      0
                                  ],
                                  [
                                      112.67419036,
                                      39.265285917,
                                      0
                                  ],
                                  [
                                      112.67430339,
                                      39.265506822,
                                      0
                                  ],
                                  [
                                      112.67394335,
                                      39.265989996,
                                      0
                                  ],
                                  [
                                      112.67417171,
                                      39.266096686,
                                      0
                                  ],
                                  [
                                      112.67428475,
                                      39.266317591,
                                      0
                                  ],
                                  [
                                      112.67395057,
                                      39.266749817,
                                      0
                                  ],
                                  [
                                      112.68730652,
                                      39.272988122,
                                      0
                                  ],
                                  [
                                      112.68739782,
                                      39.2731148,
                                      0
                                  ],
                                  [
                                      112.68739782,
                                      39.2731148,
                                      0
                                  ],
                                  [
                                      112.68739782,
                                      39.2731148,
                                      0
                                  ],
                                  [
                                      112.68739782,
                                      39.2731148,
                                      0
                                  ],
                                  [
                                      112.68739782,
                                      39.2731148,
                                      0
                                  ],
                                  [
                                      112.68569134,
                                      39.27532242,
                                      0
                                  ],
                                  [
                                      112.68550008,
                                      39.275380179,
                                      0
                                  ],
                                  [
                                      112.68486296,
                                      39.275082652,
                                      0
                                  ],
                                  [
                                      112.68426626,
                                      39.275854536,
                                      0
                                  ],
                                  [
                                      112.68333136,
                                      39.27709882,
                                      0
                                  ]
                              ]
                          },
                          "properties": {
                              "name": "2DPolyline",
                              "styleUrl": "#ff0000ff",
                              "styleHash": "7ffb8955"
                          }
                      }
                  ]
              }})
          map.addLayer({
            id: "redLineLayer",
            type: "line",
            source: "redLineSource",
            layout: {},
            paint: {
              "line-color":"#ff0000",
              "line-width":2,
              "line-opacity":1
            },
          })
        })


    let isPlay = false
    let counter = 0
    let steps = 0
    let aLength = 0;
    let routeGeoJson = {
        'type': 'FeatureCollection',
        'features': [{
            'type': 'Feature',
            'geometry': {
                'type': 'LineString',
                'coordinates': [
                    [112.678253, 39.275592],
                        [112.678253, 39.275592],
                        [112.678253, 39.275592],
                        [112.678321, 39.275638],
                        [112.678321, 39.275638],
                        [112.678314, 39.275638],
                        [112.678298, 39.275596],
                        [112.678298, 39.275623],
                        [112.678306, 39.275608],
                        [112.678298, 39.2756],
                        [112.678291, 39.275611],
                        [112.678283, 39.27563],
                        [112.678283, 39.275588],
                        [112.678283, 39.2756],
                        [112.678276, 39.275615],
                        [112.678268, 39.275634],
                        [112.678276, 39.275653],
                        [112.678276, 39.275653],
                        [112.678276, 39.275665],
                        [112.678306, 39.275623],
                        [112.678329, 39.275615],
                        [112.678344, 39.275573],
                        [112.678337, 39.275585],
                        [112.678344, 39.275581],
                        [112.678314, 39.2756],
                        [112.678298, 39.275627],
                        [112.678306, 39.275657],
                        [112.678276, 39.275657],
                        [112.678314, 39.275615],
                        [112.678352, 39.275539],
                        [112.678359, 39.27552],
                        [112.678352, 39.275512],
                        [112.678314, 39.275569],
                        [112.678314, 39.275581],
                        [112.678314, 39.275592],
                        [112.678314, 39.275558],
                        [112.678337, 39.27555],
                        [112.678321, 39.275566],
                        [112.678291, 39.275585],
                        [112.678283, 39.275611],
                        [112.678298, 39.2756],
                        [112.678291, 39.275588]
                ]
            }
        }]
    }

    let realRouteGeoJson = {
        'type': 'FeatureCollection',
        'features': [{
            'type': 'Feature',
            'geometry': {
                'type': 'LineString',
                'coordinates': []
            }
        }]
    }

    let animatePointGeoJson = {
        'type': 'FeatureCollection',
        'features': [{
            'type': 'Feature',
            'properties': {},
            'geometry': {
                'type': 'Point',
                'coordinates': []
            }
        }]
    }

    // //查询全部回放
    // const getAllPath = ()=>{
    //     axios.post("/beta/findDeviceHistory",{deviceId:trackId.value}).then((res)=>{
    //         if(res.success){
    //             if(res.data.realData == null){
    //                 message.info("当前时间段暂无数据")
    //             }else {
    //                 let msg=[]
    //                 centerList.value=res.data.realData[0]
    //                 res.data.realData.map(function(item){
    //                     msg.push([item.longitude,item.latitude])
    //                 })
    //                 playbackMapInfo.realSource.features.push({
    //                     "type": "Feature",
    //                     "geometry": {
    //                         "type": "LineString",
    //                         "coordinates": msg
    //                     }
    //
    //                 })
    //
    //                 addRoutelayer() // 添加轨迹线图层
    //                 // 跳转位置
    //                 if ( centerList.value){
    //                     trackmap.map.setZoom(17)
    //                     let Center = new mapboxgl.LngLat( centerList.value.longitude, centerList.value.latitude );
    //                     mapToTrack(Center)
    //                 }
    //             }
    //         }else{
    //             message.info("查询数据失败")
    //         }
    //     })
    // }
    // //查询某一时间段
    // const getPathByTime = ()=>{
    //
    //     axios.post("/beta/findDeviceHistory",
    //         {deviceId:trackId.value,
    //             startTime :moment((value1.value[0]).toDate()).format('yyyy-MM-DD HH:mm:ss'),
    //             endTime:moment((value1.value[1]).toDate()).format('yyyy-MM-DD HH:mm:ss'),
    //         }).then((res)=>{
    //         if (res.success) {
    //
    //             if (res.data.realData == null) {
    //                 message.info("当前时间段暂无数据")
    //             } else {
    //                 let msg = []
    //                 playbackMapInfo.realSource.features = new Array
    //                 if (trackmap.map.getLayer('realRouteLayer')) trackmap.map.removeLayer('realRouteLayer')
    //                 if (trackmap.map.getSource('realRouteLayer')) trackmap.map.removeSource('realRouteLayer')
    //                 if (trackmap.map.getLayer('routeLayer')) trackmap.map.removeLayer('routeLayer')
    //                 if (trackmap.map.getSource('routeLayer')) trackmap.map.removeSource('routeLayer')
    //
    //
    //                 centerList.value = res.data.realData[0]
    //                 res.data.realData.map(function (item) {
    //                     msg.push([item.longitude, item.latitude])
    //                 })
    //
    //                 playbackMapInfo.realSource.features.push({
    //                     "type": "Feature",
    //                     "geometry": {
    //                         "type": "LineString",
    //                         "coordinates": msg
    //                     }
    //
    //                 })
    //                 addRoutelayer() // 添加轨迹线图层
    //                 // 跳转位置
    //                 if (centerList.value) {
    //                     trackmap.map.setZoom(17)
    //                     let Center = new mapboxgl.LngLat(centerList.value.longitude, centerList.value.latitude);
    //                     mapToTrack(Center)
    //                 }
    //             }
    //
    //         } else {
    //             message.info("查询数据失败")
    //         }
    //     })
    // }


    // 获取轨迹数据
    function setRouteData() {
        animatePointGeoJson.features[0].geometry.coordinates = routeGeoJson.features[0].geometry.coordinates[0]
        aLength = routeGeoJson.features[0].geometry.coordinates.length;
        newRouteGeoJson = resetRoute(routeGeoJson.features[0], 1000, 'kilometers')
        steps = newRouteGeoJson.geometry.coordinates.length

        addRoutelayer() // 添加轨迹线图层
        addRealRouteSource() // 添加实时轨迹线图层
        // addArrowlayer() // 添加箭头图层
        addAnimatePointSource() // 添加动态点图层
    }

    // 添加轨迹线图层
    function addRoutelayer() {
        map.addLayer({
            'id': 'routeLayer',
            'type': 'line',
            'source': {
                'type': 'geojson',
                'lineMetrics': true,
                'data': routeGeoJson
            },
            'paint': {
                'line-width': 10,
                'line-opacity': 1,
                'line-color': '#D0D0D0',
            }
        });
    }

    // 添加实时轨迹线
    function addRealRouteSource() {
        map.addLayer({
            'id': 'realRouteLayer',
            'type': 'line',
            'source': {
                'type': 'geojson',
                'lineMetrics': true,
                'data': realRouteGeoJson
            },
            'paint': {
                'line-width': 10,
                'line-opacity': 1,
                'line-color': '#FF0000',
            }
        });
    }

    // // 添加箭头图层
    // function addArrowlayer() {
    //     map.addLayer({
    //         'id': 'arrowLayer',
    //         'type': 'symbol',
    //         'source': {
    //             'type': 'geojson',
    //             'data': routeGeoJson //轨迹geojson格式数据
    //         },
    //         'layout': {
    //             'symbol-placement': 'line',
    //             'symbol-spacing': 50, // 图标间隔，默认为250
    //             'icon-image': 'arrowIcon', //箭头图标
    //             'icon-size': 0.5
    //         }
    //     });
    // }

    // 添加动态点图层
    function addAnimatePointSource() {
        map.addLayer({
            'id': 'animatePointLayer',
            'type': 'symbol',
            'source': {
                'type': 'geojson',
                'data': animatePointGeoJson
            },
            'layout': {
                'icon-image': 'carIcon',
                'icon-size': 0.5,
                'icon-rotate': ['get', 'bearing'],
                'icon-rotation-alignment': 'map',
                'icon-allow-overlap': true,
                'icon-ignore-placement': true
            }
        });

        animate()
    }

    const animate=()=> {
        if (counter >= steps) {
            return
        }
        let startPnt, endPnt
        if (counter == 0) {
            realRouteGeoJson.features[0].geometry.coordinates = []
            startPnt = newRouteGeoJson.geometry.coordinates[counter]
            endPnt = newRouteGeoJson.geometry.coordinates[counter + 1]
        } else if (counter !== 0) {
            startPnt = newRouteGeoJson.geometry.coordinates[counter - 1]
            endPnt = newRouteGeoJson.geometry.coordinates[counter]
        }

        animatePointGeoJson.features[0].properties.bearing = turf.bearing(
            turf.point(startPnt),
            turf.point(endPnt)
        ) - 90;
        animatePointGeoJson.features[0].geometry.coordinates = newRouteGeoJson.geometry.coordinates[counter];
        realRouteGeoJson.features[0].geometry.coordinates.push(animatePointGeoJson.features[0].geometry.coordinates)

        map.getSource('animatePointLayer').setData(animatePointGeoJson);
        map.getSource('realRouteLayer').setData(realRouteGeoJson);
        if (isPlay) {
            requestAnimationFrame(animate);
        }
        counter = counter + 1;
    }

    const resetRoute=(route, nstep, units)=> {
        let newroute = {
            'type': 'Feature',
            'geometry': {
                'type': 'LineString',
                'coordinates': []
            }
        }
        let lineDistance = turf.lineDistance(route);
        let nDistance = lineDistance / nstep;
        for (let i = 0; i < aLength - 1; i++) {
            let from = turf.point(route.geometry.coordinates[i]);
            let to = turf.point(route.geometry.coordinates[i + 1]);
            let lDistance = turf.distance(from, to, units);
            if (i == 0) {
                newroute.geometry.coordinates.push(route.geometry.coordinates[0])
            }
            if (lDistance > nDistance) {
                let rings = lineMore(from, to, lDistance, nDistance, units)
                newroute.geometry.coordinates = newroute.geometry.coordinates.concat(rings)
            } else {
                newroute.geometry.coordinates.push(route.geometry.coordinates[i + 1])
            }
        }
        return newroute
    }

    const  lineMore=(from, to, distance, splitLength, units)=> {
        let step = distance / splitLength
        let leftLength = distance - step * splitLength
        let rings = []
        let route = turf.lineString([from.geometry.coordinates, to.geometry.coordinates])
        for (let i = 1; i <= step; i++) {
            let nlength = i * splitLength
            let pnt = turf.along(route, nlength, units);
            rings.push(pnt.geometry.coordinates)
        }
        if (leftLength > 0) {
            rings.push(to.geometry.coordinates)
        }
        return rings
    }

    function startClick() {
         setRouteData()
        console.log('开始')
        if (!isPlay) {
            isPlay = true
            animate()
        }
    }

    function pauseClick() {
        isPlay = false
        animate()
    }

    function stopClick() {
        isPlay = false
        counter = 0
        animate()
    }

</script>

</body>

</html>